<script setup lang="ts">
import {
  watch,
  triggerRef,
  shallowRef,
  shallowReactive,
  shallowReadonly,
} from "vue";
import { useDebounceRef } from "@/composible/useDebounceRef";

const count = useDebounceRef(0, 500);

watch(count, (newVal, oldVal) => {
  console.log("watch count:", newVal, oldVal);
});

const base = shallowRef({
  value: 6,
});

const baseShallowChange = () => {
  base.value.value++;
};
const handleTrigger = () => {
  triggerRef(base);
};

watch(
  () => base.value,
  (newVal, oldVal) => {
    console.log("watch base:", newVal, oldVal);
  },
);

const complex = shallowReactive({
  name: "Jony",
  score: 1,
  time: "33s",
  hobbies: [
    {
      name: "艺术",
      scope: [
        {
          name: "唱歌",
          rule: ["中国", "美国", "日本"],
        },
        {
          name: "画画",
          rule: ["中国", "美国", "日本"],
        },
      ],
    },
    {
      name: "运动",
      scope: [
        {
          name: "足球",
          rule: ["中国", "美国", "日本"],
        },
      ],
    },
  ],
});

const complexShallowChange = () => {
  complex.score++;
};

const complexDeepChange = () => {
  complex.hobbies[0].scope.push({
    name: "绘画",
    rule: ["中国", "美国", "日本"],
  });
};

const complexSD = () => {
  complex.hobbies[1].scope.push({
    name: "dance",
    rule: ["kpop", "jpop", "pop"],
  });
  complex.time = new Date().getSeconds() + "s"; // time重新渲染，才会一起渲染深层改变。如果time不变，不会触发深层的一起渲染
};

watch(
  () => complex,
  (newVal, oldVal) => {
    console.log("watch complex:", newVal, oldVal);
  },
  { deep: true }, // 深度监听为true,才会监听到complex内部的变化
);

watch(
  () => complex.name,
  (newVal, oldVal) => {
    console.log("watch complex name:", newVal, oldVal);
  },
);

const readonlyInfo = shallowReadonly({
  name: "readonly",
  age: 18,
  language: [
    {
      id: 1,
      name: "中文",
    },
    {
      id: 2,
      name: "英文",
    },
  ],
  job: {
    id: 1,
    name: "前端",
    scope: ["vue", "react", "angular"],
  },
});

const readonlyShallowChange = () => {
  // readonlyInfo.name = "name changed";
};

const readonlyDeepChange = () => {
  readonlyInfo.job.scope.push("node");
};

watch(
  () => readonlyInfo,
  (newVal, oldVal) => {
    console.log("watch readonlyInfo:", newVal, oldVal);
  },
);
</script>

<template>
  <h1>浅层响应式</h1>

  <div class="card">
    <h2>customRef</h2>
    延迟更新：count is {{ count }}
    <button type="button" @click="count++">+ 1</button>
  </div>
  <div class="card">
    <h2>shallowRef & triggerRef</h2>
    手动更新 number: {{ base.value }}
    <button type="button" @click="baseShallowChange">+ 1</button>
    <button type="button" @click="handleTrigger">triggerRef</button>
  </div>
  <div class="card">
    <h2>shallowReactive</h2>
    <button type="button" @click="complexShallowChange">score + 1</button>
    <button type="button" @click="complexDeepChange">complex deep</button>
    <button type="button" @click="complexSD">complex shallow & deep</button>
    <div>{{ complex }}</div>
  </div>
  <div class="card">
    <h2>shallowReadonly</h2>
    <button type="button" @click="readonlyShallowChange">change shallow</button>
    <button type="button" @click="readonlyDeepChange">change deep</button>
    <div>{{ readonlyInfo }}</div>
  </div>
</template>

<style scoped>
.read-the-docs {
  color: #888;
}
</style>
